package org.parademo.dao;

import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.parademo.exception.DaoException;
import org.parademo.model.ProposalEntity;

import java.util.List;

public class ProposalDao extends GenericDao<ProposalEntity> {

    public ProposalDao(SessionFactory sessionFactory) {
        super(sessionFactory);
    }

    public ProposalEntity retrieve(long proposalId) {
        Query query = getCurrentSession().createQuery(
                "select\n" +
                "    p\n" +
                "from\n" +
                "    ProposalEntity p\n" +
                "        left join fetch p.topic\n" +
                "        left join fetch p.status\n" +
                "where\n" +
                "    p.id = :proposalId"
        );

        query.setLong("proposalId", proposalId);

        @SuppressWarnings("unchecked")
        List<ProposalEntity> proposals = query.list();

        int proposalsCount = proposals.size();
        if (proposalsCount == 0) {
            return null;
        }
        if (proposalsCount > 1) {
            throw new DaoException("found multiple proposals with the id [" + proposalId + "]: " + proposals);
        }

        return proposals.get(0);
    }

    public void create(ProposalEntity entityToCreate) {
        getCurrentSession().save(entityToCreate);
    }

    public void update(ProposalEntity entityToUpdate) {
        throw new UnsupportedOperationException("unimplemented"); // todo: implement this
    }

    public void delete(ProposalEntity entityToDelete) {
        throw new UnsupportedOperationException("unimplemented"); // todo: implement this
    }

    public List<ProposalEntity> getProposalsForUser(long userId) {
        Query query = getCurrentSession().createQuery(
                "select\n" +
                "    p\n" +
                "from\n" +
                "    ProposalEntity p\n" +
                "        left join fetch p.topic\n" +
                "        left join fetch p.status\n" +
                "where\n" +
                "    p.author.id = :userId"
        );

        query.setLong("userId", userId);

        @SuppressWarnings("unchecked")
        List<ProposalEntity> proposals = query.list();

        return proposals;
    }

    public void save(ProposalEntity proposal) {
        getCurrentSession().save(proposal);
    }
}
